package com.eagle.nenaboot.server.core.handler;

import com.eagle.nenaboot.common.session.Session;
import com.eagle.nenaboot.common.protocol.ConnectPacket;
import com.eagle.nenaboot.common.protocol.DataPacket;
import com.eagle.nenaboot.common.protocol.RegisterPacket;
import com.eagle.nenaboot.common.utils.SessionUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;


/**
 * 1. 客户端连上netty服务器后，马上调用handlerAdded方法完成channel的添加操作(所谓channel可以理解为一个客户端)
 *
 * 2. 添加操作执行完成以后立马调用channelRegistered方法将channel注入到netty中管理起来
 *
 * 3. 注册好以后调用服务器端的channelActive方法，让其处于激活状态
 *
 * 4. 调用channelRead0方法完成客户端数据的读取和相应
 *
 * <p>
 *  跟客户端 通信的拦截器
 * <p>
 *
 * @author eagle liu
 * @since 2020/3/13 21:14
 */
@Slf4j
public class ServerHandler extends ChannelInboundHandlerAdapter {

	/**
	 * 第二步: 10240服务端接入
	 * 当有客户端连接的时候触发
	 *
	 * @param ctx
	 */
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
		log.info("第二步，有新客户端连接接入。。。"+ctx.channel().remoteAddress());
    }



    public ServerHandler() {}

    /**
	 * 第三步: 10240服务端接收数据，持久化了channel，并向客户端写回数据RegisterPacket
	 *
	 * 当channel上面有数据到来时会触发channelRead事件，当数据到来时，
	 * eventLoop被唤醒继而调用channelRead方法处理数据
	 *
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg){
        if (msg instanceof RegisterPacket) {
            RegisterPacket registerPacket = (RegisterPacket) msg;
            if (StringUtils.isNotEmpty(registerPacket.getToken())){
//                这里持久化了channel，当在80端口的服务端触发时候会根据token拿到这个10240的channel，并向它发包
//				这样10240客户端就能收到这个包了
            	SessionUtil.bindSession(new Session(registerPacket.getToken()),ctx.channel());
				SessionUtil.setToken(registerPacket.getToken());
                log.info("第三步，Token: {},链接服务器成功", registerPacket.getToken());
                registerPacket.setSuccess(true);
                registerPacket.setMessage("connect success");
                ctx.channel().writeAndFlush(registerPacket);
            }else {
                registerPacket.setSuccess(false);
                registerPacket.setMessage("Token is wrong");
                ctx.writeAndFlush(registerPacket);
            }
        }else if (msg instanceof ConnectPacket){
            log.info("链接信息");
        }else if(msg instanceof DataPacket){
			log.info("第八步，接收到代理端口（比如3306）客户端发过来的DataPacket，然后拿到80服务端的channel，" +
					"向这个channel写入数据，客户端（访问者）就可以拿到数据了，此时请求数据完毕");
            DataPacket dataPacket = (DataPacket) msg;
            //这个是第五步connectPack设置好的channel,即80服务端的channel，向这个channel写入数据，客户端（访问者）就可以拿到数据了
            Channel channel = SessionUtil.getChannelByChannelId(dataPacket.getChannelId());
            channel.writeAndFlush(dataPacket.getBytes());
        }
    }
}
